home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / menu / biosio.c next >
Encoding:
C/C++ Source or Header  |  2004-12-30  |  7.4 KB  |  366 lines

  1. /* -*- c -*- ------------------------------------------------------------- *
  2.  *   
  3.  *   Copyright 2004 Murali Krishnan Ganapathy - All Rights Reserved
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
  8.  *   Boston MA 02111-1307, USA; either version 2 of the License, or
  9.  *   (at your option) any later version; incorporated herein by reference.
  10.  *
  11.  * ----------------------------------------------------------------------- */
  12.  
  13. #include "string.h"
  14. #include "biosio.h"
  15.  
  16. /*
  17.  * Note: don't use "r" or "g" for 8-bit values.  Some versions of gcc
  18.  * will actually try to generate x86-64 registers that way!  Use
  19.  * "abcd" or "abcdmi", respectively.  Newer gccs have the newer "q"
  20.  * and "Q" constraints, but older gccs don't know those.
  21.  */
  22.  
  23. /* BIOS Assisted output routines */
  24.  
  25. void bios_int10(void)
  26. {
  27.   asm volatile("pushl %ebp ; int $0x10 ; popl %ebp");
  28. }
  29.  
  30. /* Print character and attribute at cursor */
  31. static inline void asm_cprint(char chr, char attr, int times, char disppage)
  32. {
  33.     asm volatile("movb $0x09,%%ah ; call bios_int10"
  34.          : "+a" (chr) : "b" (attr + (disppage << 8)), "c" (times));
  35. }
  36.  
  37. void cprint(char chr,char attr,int times,char disppage)
  38. {
  39.     asm_cprint(chr,attr,times,disppage);
  40. }
  41.  
  42. static inline void asm_setdisppage(char num)
  43. {
  44.     asm volatile("movb $0x05,%%ah ; call bios_int10"
  45.          : "+a" (num));
  46. }
  47.  
  48. void setdisppage(char num) // Set the display page to specified number
  49. {
  50.     asm_setdisppage(num);
  51. }
  52.  
  53. static inline char asm_getdisppage(void)
  54. {
  55.     char page;
  56.     
  57.     asm("movb $0x0f,%%ah ; "
  58.     "call bios_int10 ; "
  59.     "movb %%bh,%0"
  60.     : "=abcdm" (page) : : "eax");
  61.     return page;
  62. }
  63.  
  64. char getdisppage() // Get current display page 
  65. {
  66.     return asm_getdisppage();
  67. }
  68.  
  69. static inline void asm_getpos(char *row, char *col, char page)
  70. {
  71.     asm("movb %2,%%bh ; "
  72.     "movb $0x03,%%ah ; "
  73.     "call bios_int10 ; "
  74.     "movb %%dh,%0 ; "
  75.     "movb %%dl,%1"
  76.     : "=m" (*row), "=m" (*col)
  77.     : "abcdmi" (page)
  78.     : "eax", "ebx", "ecx", "edx");
  79. }
  80.  
  81. void getpos(char * row, char * col, char page)
  82. {
  83.     asm_getpos(row,col,page);
  84. }
  85.  
  86. static inline void asm_gotoxy(char row,char col, char page)
  87. {
  88.     asm volatile("movb %1,%%bh ; "
  89.          "movb $0x02,%%ah ; "
  90.          "call bios_int10"
  91.          : : "d" ((row << 8) + col), "abcdmi" (page)
  92.          : "eax", "ebx");
  93. }
  94.  
  95. void gotoxy(char row,char col, char page)
  96. {
  97.     asm_gotoxy(row,col,page);
  98. }
  99.  
  100. static inline unsigned char asm_sleep(unsigned int milli)
  101. { // ah = 86, int 15, cx:dx = microseconds
  102.   // mul op16 : dx:ax = ax * op16
  103.   unsigned char ans;
  104.   asm volatile ("mul  %%cx; "
  105.         "xchg %%dx, %%ax; "
  106.         "movw %%ax, %%cx; "
  107.         "movb $0x86, %%ah;"
  108.         "int $0x15;"
  109.         "setnc %0"
  110.         : "=r" (ans) 
  111.         : "a" (milli), "c" (1000)
  112.         : "edx");
  113.   return ans;
  114. }
  115.  
  116. unsigned char sleep(unsigned int msec)
  117. {
  118.  return asm_sleep(msec);
  119. }
  120.  
  121. void asm_beep()
  122. {
  123.   // For a beep the page number (bh) does not matter, so set it to zero
  124.   asm volatile("movw $0x0E07, %%ax;"
  125.            "xor  %%bh,%%bh;"
  126.            "call bios_int10"
  127.            : : : "eax","ebx");
  128. }
  129.  
  130. void beep()
  131. {
  132.   asm_beep();
  133. }
  134.  
  135. static inline void asm_putchar(char x, char attr,char page)
  136. {
  137.     asm volatile("movb %1,%%bh;"
  138.          "movb %2,%%bl;"
  139.          "movb $0x09,%%ah;"
  140.          "movw $0x1, %%cx;"
  141.          "call bios_int10"
  142.          : "+a" (x)
  143.          : "abcdmi" (page), "acdmi" (attr)
  144.          : "ebx", "ecx");
  145. }
  146.  
  147. void putch(char x, char attr, char page)
  148. {
  149.   asm_putchar(x,attr,page);
  150. }
  151.  
  152. void scrollup()
  153. {
  154.   unsigned short dx = (getnumrows()<< 8) + getnumcols();
  155.   
  156.   asm volatile("movw $0x0601, %%ax;"
  157.            "movb $0x07, %%bh;"
  158.            "xor %%cx, %%cx;"
  159.            "call bios_int10"
  160.            : "+d" (dx)
  161.            : : "eax","ebx","ecx");
  162. }
  163.  
  164. /* Print a C string (NUL-terminated) */
  165. void csprint(const char *str,char attr)
  166. {
  167.     char page = asm_getdisppage();
  168.     char newattr=0,cha,chb;
  169.     char row,col;
  170.  
  171.     asm_getpos(&row,&col,page);
  172.     while ( *str ) {
  173.       switch (*str) 
  174.     {
  175.     case '\b':
  176.       --col;
  177.       break;
  178.     case '\n':
  179.       ++row;
  180.       break;
  181.     case '\r':
  182.       col=0;
  183.       break;
  184.     case BELL: // Bell Char
  185.       asm_beep();
  186.       break;
  187.     case CHRELATTR: // change attribute (relatively)
  188.     case CHABSATTR: // change attribute (absolute)
  189.       cha = *(str+1);
  190.       chb = *(str+2);
  191.       if ((((cha >= '0') && (cha <= '9')) || 
  192.            ((cha >= 'A') && (cha <= 'F'))) &&
  193.           (((chb >= '0') && (chb <= '9')) || 
  194.            ((chb >= 'A') && (chb <= 'F')))) // Next two chars are legal
  195.         {
  196.           if ((cha >= 'A') && (cha <= 'F'))
  197.         cha = cha - 'A'+10;
  198.           else cha = cha - '0';
  199.           if ((chb >= 'A') && (chb <= 'F'))
  200.         chb = chb - 'A'+10;
  201.           else chb = chb - '0';
  202.           newattr = (cha << 4) + chb;
  203.           attr = (*str == CHABSATTR ? newattr : attr ^ newattr);
  204.           str += 2; // Will be incremented again later
  205.         }
  206.       break;
  207.     default:
  208.       asm_putchar(*str, attr, page);
  209.       ++col;
  210.     }
  211.       if (col > getnumcols())
  212.     {
  213.       ++row;
  214.       col=0;
  215.     }
  216.       if (row > getnumrows())
  217.     {
  218.       scrollup();
  219.       row= getnumrows();
  220.     }
  221.       asm_gotoxy(row,col,page);
  222.       str++;
  223.     }
  224. }
  225.  
  226. void clearwindow(char top, char left, char bot, char right, char page, char fillchar, char fillattr)
  227. {
  228.     char x;
  229.     for (x=top; x < bot+1; x++)
  230.     {
  231.         gotoxy(x,left,page);
  232.         asm_cprint(fillchar,fillattr,right-left+1,page);
  233.     }
  234. }
  235.  
  236. void cls(void)
  237. {
  238.     gotoxy(0,0,getdisppage());
  239.     asm_cprint(' ',0x07,getnumrows()*getnumcols(),getdisppage());
  240. }
  241.  
  242. char asm_inputc(char *scancode)
  243. {
  244.   unsigned short ax;
  245.  
  246.   asm volatile("movb $0x10,%%ah ; "
  247.            "int $0x16"
  248.            : "=a" (ax));
  249.   
  250.   if (scancode)
  251.       *scancode = (ax >> 8);
  252.   
  253.   return (char)ax;
  254. }
  255.    
  256. char inputc(char * scancode)
  257. {
  258.     return asm_inputc(scancode);
  259. }
  260.  
  261. static inline void asm_cursorshape(char start, char end)
  262. {
  263.     asm volatile("movb $0x01,%%ah ; int $0x10"
  264.          : : "c" ((start << 8) + end) : "eax");
  265. }
  266.  
  267. void cursoroff(void)
  268. {
  269.     asm_cursorshape(32,32);
  270. }
  271.  
  272. void cursoron(void)
  273. {
  274.     asm_cursorshape(6,7);
  275. }
  276.  
  277. char bkspstr[] = " \b$";
  278. char eolstr[] = "\n$";
  279.  
  280. static inline char asm_getchar(void)
  281. {
  282.     char v;
  283.     
  284.     /* Get key without echo */
  285.     asm("movb $0x08,%%ah ; int $0x21" : "=a" (v));
  286.     
  287.     return v;
  288. }
  289.  
  290. #define GETSTRATTR 0x07
  291.  
  292. // Reads a line of input from stdin. Replace CR with NUL byte
  293. void getstring(char *str, unsigned int size)
  294. {
  295.     char c;
  296.     char *p = str;
  297.     char page = asm_getdisppage();
  298.     char row,col;
  299.  
  300.     while ( (c = asm_getchar()) != '\r' ) {
  301.     switch (c) {
  302.     case '\0':        /* Extended char prefix */
  303.         asm_getchar();    /* Drop */
  304.         break;
  305.     case '\b':
  306.         if ( p > str ) {
  307.         p--;
  308.         csprint("\b \b",GETSTRATTR);
  309.         }
  310.         break;
  311.     case '\x15':        /* Ctrl-U: kill input */
  312.         while ( p > str ) {
  313.         p--;
  314.         csprint("\b \b",GETSTRATTR);
  315.         }
  316.         break;
  317.     default:
  318.         if ( c >= ' ' && (unsigned int)(p-str) < size-1 ) {
  319.           *p++ = c;
  320.           asm_getpos(&row,&col,page);
  321.           asm_putchar(c, GETSTRATTR, page);
  322.           asm_gotoxy(row,col+1,page);
  323.         }
  324.         break;
  325.     }
  326.     }
  327.     *p = '\0';
  328.     csprint("\r\n",GETSTRATTR);
  329. }
  330.  
  331. static inline void asm_setvideomode(char mode)
  332. {
  333.     /* This BIOS function is notoriously register-dirty,
  334.        so push/pop around it */
  335.     asm volatile("pushal ; xorb %%ah,%%ah ; int $0x10 ; popal"
  336.          : : "a" (mode) );
  337. }
  338.  
  339. void setvideomode(char mode)
  340. {
  341.     asm_setvideomode(mode);
  342. }
  343.  
  344. static inline unsigned char asm_checkkbdbuf()
  345. {
  346.   unsigned char ans;
  347.  
  348.   asm volatile("movb $0x11, %%ah;"
  349.            "int $0x16 ;"
  350.            "setnz %0;"
  351.            : "=abcdm" (ans)
  352.            : 
  353.            : "eax");
  354.   return ans;
  355. }
  356.  
  357. unsigned char checkkbdbuf()
  358. {
  359.   return asm_checkkbdbuf();
  360. }
  361.  
  362. void clearkbdbuf()
  363. {
  364.   while (asm_checkkbdbuf()) asm_inputc(NULL);
  365. }
  366.